#include "Date.h"

#include <string.h>
#include <fan-llvm/core/Core.h>
#include "Type.h"
#include "UnsupportedErr.h"


Type* Date_classType = NULL;
VTable* Date_classVTable = NULL;


/**********************************************
 *
 * Methods and fields
 *
 **********************************************/


/* Bool equals(Obj? that) */
Bool Date_equals(Obj self, NullableObj that)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Date.equals not implemented yet"));
}


/* Int compare(Obj obj) */
Int Date_compare(Obj self, Obj obj)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Date.compare not implemented yet"));
}


/* Int hash() */
Int Date_hash(Obj self)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Date.hash not implemented yet"));
}


/* Str toStr() */
Str* Date_toStr(Obj self)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Date.toStr not implemented yet"));
}


/* Date defVal */
Date* Date_defVal(void)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Date.defVal not implemented yet"));
}


/* Date today(TimeZone tz) */
Date* Date_today_0(void)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Date.today not implemented yet"));
}


/* Date today(TimeZone tz) */
Date* Date_today(TimeZone* tz)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Date.today not implemented yet"));
}


/* Date make(Int year, Month month, Int day) */
Date* Date_make(Int year, Month* month, Int day)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Date.make not implemented yet"));
}


/* Date? fromStr(Str s, Bool checked) */
Date* Date_fromStr_1(Str* s)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Date.fromStr not implemented yet"));
}


/* Date? fromStr(Str s, Bool checked) */
Date* Date_fromStr(Str* s, Bool checked)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Date.fromStr not implemented yet"));
}


/* Int year() */
Int Date_year(Date* self)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Date.year not implemented yet"));
}


/* Month month() */
Month* Date_month(Date* self)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Date.month not implemented yet"));
}


/* Int day() */
Int Date_day(Date* self)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Date.day not implemented yet"));
}


/* Weekday weekday() */
Weekday* Date_weekday(Date* self)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Date.weekday not implemented yet"));
}


/* Int dayOfYear() */
Int Date_dayOfYear(Date* self)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Date.dayOfYear not implemented yet"));
}


/* Str toLocale(Str? pattern) */
Str* Date_toLocale_0(Date* self)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Date.toLocale not implemented yet"));
}


/* Str toLocale(Str? pattern) */
Str* Date_toLocale(Date* self, Str* pattern)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Date.toLocale not implemented yet"));
}


/* Date? fromLocale(Str str, Str pattern, Bool checked) */
Date* Date_fromLocale_2(Str* str, Str* pattern)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Date.fromLocale not implemented yet"));
}


/* Date? fromLocale(Str str, Str pattern, Bool checked) */
Date* Date_fromLocale(Str* str, Str* pattern, Bool checked)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Date.fromLocale not implemented yet"));
}


/* Date? fromIso(Str s, Bool checked) */
Date* Date_fromIso_1(Str* s)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Date.fromIso not implemented yet"));
}


/* Date? fromIso(Str s, Bool checked) */
Date* Date_fromIso(Str* s, Bool checked)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Date.fromIso not implemented yet"));
}


/* Str toIso() */
Str* Date_toIso(Date* self)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Date.toIso not implemented yet"));
}


/* Date plus(Duration days) */
Date* Date_plus(Date* self, Duration* days)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Date.plus not implemented yet"));
}


/* Date minus(Duration days) */
Date* Date_minus(Date* self, Duration* days)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Date.minus not implemented yet"));
}


/* Duration minusDate(Date days) */
Duration* Date_minusDate(Date* self, Date* days)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Date.minusDate not implemented yet"));
}


/* Date firstOfMonth() */
Date* Date_firstOfMonth(Date* self)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Date.firstOfMonth not implemented yet"));
}


/* Date lastOfMonth() */
Date* Date_lastOfMonth(Date* self)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Date.lastOfMonth not implemented yet"));
}


/* Bool isYesterday() */
Bool Date_isYesterday(Date* self)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Date.isYesterday not implemented yet"));
}


/* Bool isToday() */
Bool Date_isToday(Date* self)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Date.isToday not implemented yet"));
}


/* Bool isTomorrow() */
Bool Date_isTomorrow(Date* self)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Date.isTomorrow not implemented yet"));
}


/* DateTime toDateTime(Time t, TimeZone tz) */
DateTime* Date_toDateTime_1(Date* self, Time* t)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Date.toDateTime not implemented yet"));
}


/* DateTime toDateTime(Time t, TimeZone tz) */
DateTime* Date_toDateTime(Date* self, Time* t, TimeZone* tz)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Date.toDateTime not implemented yet"));
}


/* DateTime midnight(TimeZone tz) */
DateTime* Date_midnight_0(Date* self)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Date.midnight not implemented yet"));
}


/* DateTime midnight(TimeZone tz) */
DateTime* Date_midnight(Date* self, TimeZone* tz)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Date.midnight not implemented yet"));
}


/* Str toCode() */
Str* Date_toCode(Date* self)
{
  exceptionThrow(UnsupportedErr_newWithFormattedMsg("sys::Date.toCode not implemented yet"));
}


/**********************************************
 *
 * Type-system functions
 *
 **********************************************/


Type* Date_initType(void)
{
  if (Date_classType == NULL)
  {
    Type* baseType = Obj_initType();
    VTable* vtable = Date_initVTable();
    Type* type = Type_new("Date", baseType, vtable, sizeof(Date), sizeof(DateVTable));
    Type_registerMethodImplementation(type, "compare", Date_compare, 1);
    Type_registerMethodImplementation(type, "day", Date_day, 0);
    Type_registerMethodImplementation(type, "dayOfYear", Date_dayOfYear, 0);
    Type_registerMethodImplementation(type, "equals", Date_equals, 1);
    Type_registerMethodImplementation(type, "firstOfMonth", Date_firstOfMonth, 0);
    Type_registerMethodImplementation(type, "fromIso", Date_fromIso_1, 1);
    Type_registerMethodImplementation(type, "fromIso", Date_fromIso, 2);
    Type_registerMethodImplementation(type, "fromLocale", Date_fromLocale_2, 2);
    Type_registerMethodImplementation(type, "fromLocale", Date_fromLocale, 3);
    Type_registerMethodImplementation(type, "fromStr", Date_fromStr_1, 1);
    Type_registerMethodImplementation(type, "fromStr", Date_fromStr, 2);
    Type_registerMethodImplementation(type, "hash", Date_hash, 0);
    Type_registerMethodImplementation(type, "isToday", Date_isToday, 0);
    Type_registerMethodImplementation(type, "isTomorrow", Date_isTomorrow, 0);
    Type_registerMethodImplementation(type, "isYesterday", Date_isYesterday, 0);
    Type_registerMethodImplementation(type, "lastOfMonth", Date_lastOfMonth, 0);
    Type_registerMethodImplementation(type, "make", Date_make, 3);
    Type_registerMethodImplementation(type, "midnight", Date_midnight_0, 0);
    Type_registerMethodImplementation(type, "midnight", Date_midnight, 1);
    Type_registerMethodImplementation(type, "minus", Date_minus, 1);
    Type_registerMethodImplementation(type, "minusDate", Date_minusDate, 1);
    Type_registerMethodImplementation(type, "month", Date_month, 0);
    Type_registerMethodImplementation(type, "plus", Date_plus, 1);
    Type_registerMethodImplementation(type, "toCode", Date_toCode, 0);
    Type_registerMethodImplementation(type, "toDateTime", Date_toDateTime_1, 1);
    Type_registerMethodImplementation(type, "toDateTime", Date_toDateTime, 2);
    Type_registerMethodImplementation(type, "toIso", Date_toIso, 0);
    Type_registerMethodImplementation(type, "toLocale", Date_toLocale_0, 0);
    Type_registerMethodImplementation(type, "toLocale", Date_toLocale, 1);
    Type_registerMethodImplementation(type, "toStr", Date_toStr, 0);
    Type_registerMethodImplementation(type, "today", Date_today_0, 0);
    Type_registerMethodImplementation(type, "today", Date_today, 1);
    Type_registerMethodImplementation(type, "weekday", Date_weekday, 0);
    Type_registerMethodImplementation(type, "year", Date_year, 0);
    Type_registerFieldImplementation(type, "defVal", Date_defVal, NULL);
    Date_classType = type;
    Date_initStatic();
  }
  return Date_classType;
}


VTable* Date_initVTable(void)
{
  if (Date_classVTable == NULL)
  {
    VTable* vtable = memoryAlloc(sizeof(DateVTable));
    memcpy(vtable, Obj_initVTable(), sizeof(FanObjVTable));
    ((FanObjVTable*)vtable)->compare = Date_compare;
    ((FanObjVTable*)vtable)->equals = Date_equals;
    ((FanObjVTable*)vtable)->hash = Date_hash;
    ((FanObjVTable*)vtable)->toStr = Date_toStr;
    Date_classVTable = vtable;
  }
  return Date_classVTable;
}


void Date_initStatic(void)
{
}
